#ifndef __flash_C
#define __flash_C

#include "flash.h"     
#include "stdio.h"      

volatile FMC_STATUS_T FLASHStatus = FMC_STATUS_COMPLETE;

// 普通参数保存
void flash_rw_init(){	  
    uint8_t i = 0;	
	  for(i = 0; i < Write_Data_size; i++){
			  writeData[i].intData = 0xffffffff;
		}		
}

// 普通参数数据写入：
void flash_write(){
	  uint32_t writeAddress = BANK1_WRITE_START_ADDR;
	  uint8_t i = 0;
	  #ifdef SYS_DEBUG
	  //printf("flash_write = %d \n",writeData[i].intData);
	  #endif
	  FMC_Unlock();
	  // FMC置空标记：FMC_FLAG_OC = 操作结束；FMC_FLAG_PE = FMC程序错误；FMC_FLAG_WPE = 写保护错误；
	  //#ifdef AT32F403AVGT7
	  //flash_flag_clear(FLASH_PRGMERR_FLAG | FLASH_EPPERR_FLAG);
	  //#else
    FMC_ClearStatusFlag((FMC_FLAG_T)(FMC_FLAG_OC | FMC_FLAG_PE | FMC_FLAG_WPE));
	  //#endif
	  FLASHStatus = FMC_ErasePage(writeAddress); // 只清除第1页;大小 = FLASH_PAGE_SIZE = 1K 或 2K    
	  // 写入数据：
    while((writeAddress <= BANK1_WRITE_END_ADDR) && (FLASHStatus == FMC_STATUS_COMPLETE) && i < Write_Data_size){			  
        FLASHStatus = FMC_ProgramWord(writeAddress, writeData[i].intData);
			  if(FLASHStatus != FMC_STATUS_COMPLETE){
					  // flash 写异常：
				}
        writeAddress = writeAddress + 4;
			  i++;
    }		
    FMC_Lock(); 
}

void flash_read(){
	  uint8_t i = 0;
	  uint32_t readAddress = BANK1_WRITE_START_ADDR;
	  while(i < Write_Data_size && readAddress <= BANK1_WRITE_END_ADDR){        
			  writeData[i].intData = *(__IOM uint32_t*) readAddress;        			
			  readAddress = readAddress + 4;	
        i++;		  
		}
}

#if LOG_ON > 0 && Nor_Flash == 0
// log数据写入：
void flash_log_write(){
	  uint32_t logEndAddress   = Page1_END_ADDR + 1;              // 初始值 = flash尾部地址
	  uint32_t logStartAddress = logEndAddress - FLASH_PAGE_SIZE; // 初始值 = flash尾部地址
	  uint16_t log_idx  = 0;
	  uint8_t  page_idx = 0;
	  FMC_Unlock();
	  // 开始写数据
	  while(page_idx < LOGS_FLASH_PAGES && (log_idx + page_idx * Logs_Num_PerPage) < Log_Saved_Sum){
			  // FMC置空标记：FMC_FLAG_OC = 操作结束；FMC_FLAG_PE = FMC程序错误；FMC_FLAG_WPE = 写保护错误；
				FMC_ClearStatusFlag((FMC_FLAG_T)(FMC_FLAG_OC | FMC_FLAG_PE | FMC_FLAG_WPE));
				// 清除整个页
				FLASHStatus = FMC_ErasePage(logStartAddress); // 只清除第1页;大小 = FLASH_PAGE_SIZE = 1K 或 2K    
				// 写入数据：
				while(FLASHStatus == FMC_STATUS_COMPLETE && logStartAddress < logEndAddress && log_idx < Logs_Num_PerPage){
						uint8_t i = 0;
					  if((log_idx + page_idx * Logs_Num_PerPage) >= Log_Saved_Sum){
							  return;
						}
						for(i = 0; i < logDataUnionIntLen; i++){							  
								FLASHStatus = FMC_ProgramWord(logStartAddress, writeLogData[log_idx + page_idx * Logs_Num_PerPage].intData[i]);
								logStartAddress = logStartAddress + 4;
								if(FLASHStatus != FMC_STATUS_COMPLETE){
										// flash 写异常：
										
										
								}
						}
						log_idx++;
				}
				if(log_idx >= Logs_Num_PerPage){
						log_idx = 0;
						logEndAddress   = logEndAddress - FLASH_PAGE_SIZE; 
	          logStartAddress = logEndAddress - FLASH_PAGE_SIZE; 
						page_idx++;
				}
		}
    FMC_Lock(); 
}

// log数据读取
void flash_log_read(){ 
	  uint32_t logEndAddress   = Page1_END_ADDR + 1;               // 初始值 = flash尾部地址
	  uint32_t logStartAddress = logEndAddress - FLASH_PAGE_SIZE;  // 初始值 = flash尾部地址
	  uint16_t log_idx  = 0;
	  uint8_t  page_idx = 0;
	  while(page_idx < LOGS_FLASH_PAGES){
				while(FLASHStatus == FMC_STATUS_COMPLETE && logStartAddress < logEndAddress && log_idx < Logs_Num_PerPage){
						uint8_t i = 0;
					  if((log_idx + page_idx * Logs_Num_PerPage) >= Log_Saved_Sum){
							  return;
						}
						for(i = 0; i < logDataUnionIntLen; i++){	
                writeLogData[log_idx + page_idx * Logs_Num_PerPage].intData[i] = *(__IOM uint32_t*) logStartAddress; // 读取1个数据	
								logStartAddress = logStartAddress + 4;
								if(FLASHStatus != FMC_STATUS_COMPLETE){
										// flash 写异常：
										
										
								}
						}						
						log_idx++;
				}
				if(log_idx >= Logs_Num_PerPage){
						log_idx = 0;
						logEndAddress   = logEndAddress - FLASH_PAGE_SIZE; 
	          logStartAddress = logEndAddress - FLASH_PAGE_SIZE; 
						page_idx++;
				}
		}
}

#endif // #if LOG_ON > 0  && Nor_Flash == 0

#if CURVE_ON > 0 && Nor_Flash == 0
// log数据写入：
void flash_curv_write(){	  
	  #if LOG_ON > 0
	  uint32_t curvEndAddress   = Page1_END_ADDR + 1 - FLASH_PAGE_SIZE * 2;  // 初始值 = flash尾部地址 - log数据占据的2页
	  #else
	  uint32_t curvEndAddress   = Page1_END_ADDR + 1;                        // 初始值 = flash尾部地址
	  #endif
	  uint32_t curvStartAddress = curvEndAddress - FLASH_PAGE_SIZE;          // 初始值 = flash尾部地址
	  uint16_t curv_idx  = 0;
	  uint8_t  page_idx  = 0;
	  FMC_Unlock();
	  // 开始写数据
	  while(page_idx < Curv_FLASH_PAGES && (curv_idx + page_idx * Curv_Num_PerPage) < Curv_Saved_Sum){
			  // FMC置空标记：FMC_FLAG_OC = 操作结束；FMC_FLAG_PE = FMC程序错误；FMC_FLAG_WPE = 写保护错误；
				FMC_ClearStatusFlag((FMC_FLAG_T)(FMC_FLAG_OC | FMC_FLAG_PE | FMC_FLAG_WPE));
				// 清除整个页
				FLASHStatus = FMC_ErasePage(curvStartAddress); // 只清除第1页;大小 = FLASH_PAGE_SIZE = 1K 或 2K    
				// 写入数据：
				while(FLASHStatus == FMC_STATUS_COMPLETE && curvStartAddress < curvEndAddress && curv_idx < Curv_Num_PerPage){
						uint8_t i = 0;
					  if((curv_idx + page_idx * Curv_Num_PerPage) >= Curv_Saved_Sum){
							  return;
						}
						for(i = 0; i < curvDataUnionIntLen; i++){							  
								FLASHStatus = FMC_ProgramWord(curvStartAddress, writeCurvData[curv_idx + page_idx * Curv_Num_PerPage].intData[i]);
								curvStartAddress = curvStartAddress + 4;
								if(FLASHStatus != FMC_STATUS_COMPLETE){
										// flash 写异常：
										
										
								}
						}
						curv_idx++;
				}
				if(curv_idx >= Curv_Num_PerPage){
						curv_idx = 0;
						curvEndAddress   = curvEndAddress - FLASH_PAGE_SIZE; 
	          curvStartAddress = curvEndAddress - FLASH_PAGE_SIZE;  
						page_idx++;
				}
		}
    FMC_Lock(); 
}

// log数据读取
void flash_curv_read(){ 
	  #if LOG_ON > 0
	  uint32_t curvEndAddress   = Page1_END_ADDR + 1 - FLASH_PAGE_SIZE * 2;  // 初始值 = flash尾部地址 - log数据占据的2页
	  #else
	  uint32_t curvEndAddress   = Page1_END_ADDR + 1;                        // 初始值 = flash尾部地址
	  #endif
	  uint32_t curvStartAddress = curvEndAddress - FLASH_PAGE_SIZE;  // 初始值 = flash尾部地址
	  uint16_t curv_idx  = 0;
	  uint8_t  page_idx = 0;
	  while(page_idx < Curv_FLASH_PAGES){
				while(FLASHStatus == FMC_STATUS_COMPLETE && curvStartAddress < curvEndAddress && curv_idx < Curv_Num_PerPage){
						uint8_t i = 0;
					  if((curv_idx + page_idx * Curv_Num_PerPage) >= Curv_Saved_Sum){
							  return;
						}
						for(i = 0; i < curvDataUnionIntLen; i++){	
                writeCurvData[curv_idx + page_idx * Curv_Num_PerPage].intData[i] = *(__IOM uint32_t*) curvStartAddress; // 读取1个数据	
								curvStartAddress = curvStartAddress + 4;
								if(FLASHStatus != FMC_STATUS_COMPLETE){
										// flash 写异常：
										
										
								}
						}						
						curv_idx++;
				}
				if(curv_idx >= Curv_Num_PerPage){
						curv_idx = 0;
						curvEndAddress   = curvEndAddress - FLASH_PAGE_SIZE; 
	          curvStartAddress = curvEndAddress - FLASH_PAGE_SIZE; 
						page_idx++;
				}
		}
}

#endif // #if CURVE_ON > 0  && Nor_Flash == 0


#endif
